package cn.cttic.app.api.controller;

import cn.cttic.base.api.domain.BaseUser;
import cn.cttic.base.api.domain.vo.BaseUserVo;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import cn.cttic.app.api.domain.dto.AppChangePasswordRequest;
import cn.cttic.app.mapper.BaseUserMapper;
import cn.cttic.app.service.IBaseUserService;
import cn.cttic.common.core.constant.CacheConstants;
import cn.cttic.common.core.constant.Constants;
import cn.cttic.common.core.domain.R;
import cn.cttic.common.core.utils.StringUtils;
import cn.cttic.common.redis.utils.RedisUtils;
import cn.cttic.common.satoken.model.AppLoginUser;
import cn.cttic.common.satoken.utils.AppLoginHelper;
import cn.cttic.resource.api.RemoteSmsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;

/**
 * 移动端 - 用户接口
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/mini/user")
@Slf4j
@RefreshScope
public class AppUserController {

    private final IBaseUserService appUserService;
    private final BaseUserMapper appUserMapper;
    @DubboReference
    private final RemoteSmsService remoteSmsService;

    /**
     * 更新头像
     */
    @PostMapping("/updateAvatar")
    public R<?> updateAvatar(@RequestPart("file") MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            return R.fail("上传文件不能为空");
        }

        try {
//            if (appUserService.updateAvatar(file) > 0) {
                return R.ok(AppLoginHelper.getAppLoginUser());
//            } else {
//                return R.fail("更新头像失败");
//            }
        } catch (Exception e) {
            return R.fail("更新头像失败");
        }
    }

//    /**
//     * 设置密码
//     */
//    @PostMapping("/setPassword")
//    public R<?> setPassword(@Validated @RequestBody AppSetPasswordRequest dto) {
//
//        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//        log.warn("[APP][设置密码] 登录用户: {}", JSON.toJSONString(loginUser));
//
//        BaseUser appUser = appUserMapper.selectById(loginUser.getUserId());
//        if (!(appUser.getPassword() == null || appUser.getPhone() == null || appUser.getPhone().equals(appUser.getPassword()) || BCrypt.checkpw(appUser.getPhone(), appUser.getPassword()))) {
//            return R.fail("用户密码已存在");
//        }
//
//        String newHashPassword = BCrypt.hashpw(dto.getPassword());
//
//        if (appUserMapper.update(new UpdateWrapper<BaseUser>().set("password", newHashPassword).eq("id", loginUser.getUserId())) > 0) {
//            return R.ok("设置密码成功");
//        } else {
//            return R.fail("设置密码失败");
//        }
//    }

    /**
     * 短信重置密码
     */
//    @PostMapping("/smsResetPassword")
//    public R<?> smsResetPassword(@Validated @RequestBody AppSMSResetPasswordRequest dto) {
//
//        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//        log.warn("[APP][短信重置密码] 登录用户: {}", JSON.toJSONString(loginUser));
//
//        // TODO 短信验证爆破防止
//        String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + loginUser.getPhone());
//        if (!dto.getSmsCode().equals(code)) {
//            return R.fail("短信验证码验证失败");
//        }
//
//        if (appUserMapper.update(new UpdateWrapper<BaseUser>().set("password", null).eq("id", loginUser.getUserId())) > 0) {
//            return R.ok("短信重置密码成功");
//        } else {
//            return R.fail("短信重置密码失败");
//        }
//    }
//
//    /**
//     * 短信设置密码
//     */
//    @PostMapping("/smsChangePassword")
//    public R<?> smsChangePassword(@Validated @RequestBody AppSMSChangePasswordRequest dto) {
//
//        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//        log.warn("[APP][短信设置密码] 登录用户: {}", JSON.toJSONString(loginUser));
//
//        // TODO 短信验证爆破防止
//        String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + loginUser.getPhone());
//        if (!dto.getSmsCode().equals(code)) {
//            return R.fail("短信验证码验证失败");
//        }
//
//        String newHashPassword = BCrypt.hashpw(dto.getPassword());
//
//        if (appUserMapper.update(new UpdateWrapper<BaseUser>().set("password", newHashPassword).eq("id", loginUser.getUserId())) > 0) {
//            return R.ok("短信设置密码成功");
//        } else {
//            return R.fail("短信设置密码失败");
//        }
//    }

    /**
     * 使用密码重置密码
     */
    @PostMapping("/changePassword")
    public R<?> changePassword(@Validated @RequestBody AppChangePasswordRequest dto) {

        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
        log.warn("[APP][使用密码重置密码] 登录用户: {}", JSON.toJSONString(loginUser));

//        BaseUser loginBaseAppUser = appUserMapper.selectById(loginUser.getUserId());
//        if (!BCrypt.checkpw(dto.getOriginPassword(), loginBaseAppUser.getPassword())) {
//            return R.fail("原始密码错误");
//        }

        String newHashPassword = BCrypt.hashpw(dto.getNewPassword());

        if (appUserMapper.update(
            new LambdaUpdateWrapper<BaseUser>()
                .set(BaseUser::getPassword, newHashPassword)
                .set(BaseUser::getFirstLogin, 0)
                .set(BaseUser::getInitialPassword, 0)
                .eq(BaseUser::getId, loginUser.getUserId())) > 0) {
            return R.ok("使用密码重置密码成功");
        } else {
            return R.fail("使用密码重置密码失败");
        }
    }

    /**
     * 发送用户信息更新短信验证码
     */
//    @PostMapping("/sendUserInfoChangeMobileSMS")
//    public R<?> sendUserInfoChangeMobileSMS(@RequestBody AppSMSChangeMobileRequest dto) {
//
//        log.warn("[APP][发送用户信息更新短信验证码][开始]");
//
//        try {
//            AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//            log.warn("[APP][发送用户信息更新短信验证码] 登录用户: {}", JSON.toJSONString(loginUser));
//
//            if (StringUtils.isEmpty(loginUser.getPhone())) {
//                return R.fail("该用户未绑定手机号");
//            }
//
//            String key = CacheConstants.CAPTCHA_CODE_KEY + loginUser.getPhone();
//            String code = RandomUtil.randomNumbers(6);
//            RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
//
//            // TODO 短信验证爆破防止
//            String codeMsg = String.format(commonTemplateInfo, code, Constants.CAPTCHA_EXPIRATION);
//            SysSms sysSms = remoteSmsService.directSendSMS(dto.getDeviceFlag(), defaultApplicationName, loginUser.getPhone(), codeMsg);
//            if (!sysSms.getIsSuccess()) {
//                return R.fail("发送用户信息更新短信验证码失败");
//            } else {
//                return R.ok("发送用户信息更新短信验证码成功");
//            }
//        } catch (Exception cce) {
//            log.error("[APP][发送用户信息更新短信验证码] 异常: {}", cce);
//            return R.fail("发送用户信息更新短信验证码失败: " + cce.getMessage());
//        } catch (Exception ex) {
//            log.error("[APP][发送用户信息更新短信验证码] 异常: {}", ex);
//            return R.fail("发送用户信息更新短信验证码失败！");
//        }
//    }


//    /**
//     * 发送更换手机号短信验证码
//     */
//    @PostMapping("/sendChangeMobileSMS")
//    public R<?> sendChangeMobileSMS(@Validated @RequestBody AppSMSChangeMobileRequest dto) {
//
//        log.warn("[APP][发送更换手机号短信验证码][开始]");
//
//        try {
//            AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//            log.warn("[APP][发送更换手机号短信验证码] 登录用户: {}", JSON.toJSONString(loginUser));
//
//            String key = CacheConstants.CAPTCHA_CODE_KEY + dto.getPhone();
//            String code = RandomUtil.randomNumbers(6);
//            RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
//
//            // TODO 短信验证爆破防止
//            String codeMsg = String.format(commonTemplateInfo, code, Constants.CAPTCHA_EXPIRATION);
//            SysSms sysSms = remoteSmsService.send(dto.getPhone(), defaultApplicationName, codeMsg);
//            if (!sysSms.getIsSuccess()) {
//                return R.fail("发送更换手机号短信验证码失败");
//            } else {
//                return R.ok("发送更换手机号短信验证码成功");
//            }
//        } catch (Exception cce) {
//            log.error("[APP][发送更换手机号短信验证码] 异常: {}", cce);
//            return R.fail("发送更换手机号短信验证码失败: " + cce.getMessage());
//        } catch (Exception ex) {
//            log.error("[APP][发送更换手机号短信验证码] 异常: {}", ex);
//            return R.fail("发送更换手机号短信验证码成功！");
//        }
//    }

//    /**
//     * 手机号短信验证
//     */
//    @PostMapping("/smsValitedMobile")
//    public R<?> smsValitedMobile(@Validated @RequestBody AppSMSValidateMobileRequest dto) {
//
//        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//        log.warn("[APP][手机号短信验证] 登录用户: {}", JSON.toJSONString(loginUser));
//
//        if (StringUtils.isEmpty(loginUser.getPhone())) {
//            return R.fail("用户未设置手机号");
//        }
//
//        String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + loginUser.getPhone());
//        if (!dto.getSmsCode().equals(code)) {
//            return R.fail("手机号短信验证失败");
//        } else {
//            return R.ok("手机号短信验证成功");
//        }
//    }
//
//    /**
//     * 短信设置手机号
//     */
//    @PostMapping("/smsChangeMobile")
//    public R<?> smsChangeMobile(@Validated @RequestBody AppSMSChangeMobileRequest dto) {
//
//        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
//        log.warn("[APP][短信设置手机号] 登录用户: {}", JSON.toJSONString(loginUser));
//
//        // TODO 短信验证爆破防止
//        String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + dto.getPhone());
//        if (!dto.getSmsCode().equals(code)) {
//            return R.fail("短信验证码验证失败");
//        }
//
//        if (appUserMapper.update(new UpdateWrapper<BaseUser>().set("phone", dto.getPhone()).set("mobile", dto.getPhone()).eq("id", loginUser.getUserId())) > 0) {
//            return R.ok("短信设置手机号成功");
//        } else {
//            return R.fail("短信设置手机号失败");
//        }
//    }

    /**
     * 更新用户信息
     */
    @PostMapping("/updateAppUser")
    public R<?> updateAppUser(@RequestBody BaseUser appUser) {
        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();
        BaseUser loginBaseAppUser = appUserMapper.selectById(loginUser.getUserId());
        if (!loginBaseAppUser.getId().equals(appUser.getId())) {
            return R.fail("更新用户信息失败");
        }
//        if (loginBaseAppUser.getBirthday() != null) {
//            String oldBirthday = DateUtil.format(loginBaseAppUser.getBirthday(), DatePattern.NORM_DATE_PATTERN);
//            String newBirthday = DateUtil.format(appUser.getBirthday(), DatePattern.NORM_DATE_PATTERN);
//            if (CharSequenceUtil.isAllNotBlank(oldBirthday, newBirthday) && !CharSequenceUtil.equals(oldBirthday, newBirthday)) {
//                return R.fail("更新用户信息失败，生日信息不能再次更改");
//            }
//        }
        if (appUserMapper.updateById(appUser) > 0) {
            return R.ok(appUser);
        } else {
            return R.fail("更新用户信息失败");
        }
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/getAppUser")
    public R<?> getAppUser() {

        AppLoginUser loginUser = AppLoginHelper.getAppLoginUser();

        BaseUser appUser = appUserMapper.selectById(loginUser.getUserId());

        BaseUserVo userVo = new BaseUserVo();
        BeanUtils.copyProperties(appUser, userVo);
//        userVo.setHasSetPassword((appUser.getPassword() == null || appUser.getPhone() == null || appUser.getPhone().equals(appUser.getPassword()) || BCrypt.checkpw(appUser.getPhone(), appUser.getPassword())) ? 0 : 1);
//        userVo.setPrivilegeExplain(appUserPrivilegeService.getBaseUserPrivilegeExplain());
        return R.ok(userVo);
    }



    /**
     * 更新用户信息
     */
    @GetMapping("/sendFakeSMSCode")
    @Deprecated
    public R<String> sendFakeSMSCode(@RequestParam(value = "phone") String phone) {

        String key = CacheConstants.CAPTCHA_CODE_KEY + phone;
        String code = RandomUtil.randomNumbers(6);
        RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
        return R.ok(code);
    }

//    /**
//     * 获取微信OpenId
//     *
//     * @param code 微信授权码
//     * @return
//     */
//    @GetMapping("/getWechatOpenId")
//    public R<Map<String, String>> getWechatOpenId(@RequestParam(value = "code") String code) {
//
//        log.info("[APP][获取微信OPENID][开始]");
//
//        try {
//            //1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid
//            String url = wechatMiniProgramConfig.getRequestUrl() +
//                "?appid=" + wechatMiniProgramConfig.getAppId() +
//                "&secret=" + wechatMiniProgramConfig.getAppSecret() +
//                "&js_code=" + code +
//                "&grant_type=" + wechatMiniProgramConfig.getGrantType();
//
//            // 2. 发送请求
//            String result = HttpUtil.get(url);
//            log.info("[APP][获取微信OPENID][结果] :" + result);
//
//            Map<String, String> resultMap = new HashMap<>();
//            JSONObject jsonObject = JSONObject.parseObject(result);
//            if (jsonObject.containsKey("openid")) {
//                String openId = jsonObject.getString("openid");
//                resultMap.put("openid", openId);
//                return R.ok(resultMap);
//            } else {
//                return R.fail(jsonObject.getString("errmsg"));
//            }
//        } catch (Exception ex) {
//            log.error("[APP][获取微信OPENID] [异常]:", ex);
//            return R.fail("获取微信OPENID失败！");
//        }
//
//    }
//
//
//    /**
//     * 获取支付宝UnionId
//     *
//     * @param code 微信授权码
//     * @return
//     */
//    @GetMapping("/getAlipayUnionId")
//    public R<Map<String, String>> getAlipayUnionId(@RequestParam(value = "code") String code) {
//
//        log.info("[APP][获取支付宝UnionId][开始]");
//
//        try {
//
//            // 1. 发送请求
//            Map<String, String> resultMap = appUserService.getAlipayUnionId(code);
//            if (resultMap != null) {
//                log.info("[APP][获取支付宝UnionId][结果] :" + JSON.toJSONString(resultMap));
//                return R.ok(resultMap);
//            } else {
//                return R.fail("获取支付宝UnionId失败");
//            }
//        } catch (Exception ex) {
//            log.error("[APP][获取支付宝UnionId] [异常]:", ex);
//            return R.fail("获取支付宝UnionId失败！");
//        }
//
//    }
}
